package newFeatureOfJava8;

import java.util.*;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.ToIntFunction;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

/**
 * @author 26029
 * @date 2025/4/19
 * @description
 */
public class LearnStream {
    public static void main(String[] args) {
        // Java 的 Stream 是一个能够对其元素进行内部迭代的组件，这意味着它可以自己迭代其元素
        // stream支持惰性求值，只有触发终结操作时才计算整个操作链
        // 修改原数组是否影响流，取决于“修改数组的操作”和“流的终结操作”的先后，因为流是惰性求值，终结前修改原数组会影响流
        List<String> stringList = new ArrayList<>();
        stringList.add("2 APPLES");
        stringList.add("1 BANANA");
        stringList.add("3 BANANA");

        Stream<String> stream = stringList.stream();
        // --------------流的中间操作--------------
        // map
        stream = stream.map(new Function<String, String>() {
            @Override
            public String apply(String s) { return s.toLowerCase(); }
        });
        stream = stream.map(s -> s.toLowerCase());
        stream = stream.map(String::toLowerCase);
        // filter
        stream = stream.filter(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return !s.isBlank();
            }
        });
        stream = stream.filter(s -> !s.isBlank());
        // flatMap
        stream = stream.flatMap(new Function<String, Stream<? extends String>>() {
            @Override
            public Stream<? extends String> apply(String s) {
                String[] split = s.split(" ");
                return Arrays.stream(split);
            }
        });
        stream = stream.flatMap(s -> Arrays.stream(s.split(" ")));
        // distinct
        stream = stream.distinct();
        // --------------流的终止操作--------------
        // toList
        List<String> list = stream.toList();
        System.out.println(list);
        // count
        long count = stringList.stream().count();
        System.out.println(count);
        // anyMatch
        boolean anyMatch = stringList.stream().anyMatch(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.equals("2 APPLES");
            }
        });
        System.out.println(anyMatch);
        // allMatch
        boolean allMatch = stringList.stream().allMatch(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.length() == 8;
            }
        });
        System.out.println(allMatch);
        // nonMatch
        boolean nonMatch = stringList.stream().noneMatch(new Predicate<String>() {
            @Override
            public boolean test(String s) {
                return s.isBlank();
            }
        });
        System.out.println(nonMatch);
        // collect
        List<String> collect = stringList.stream().collect(Collectors.toList());
        System.out.println(collect);
        // findAny / findFirst
        Optional<String> any = stringList.stream().findAny();
        System.out.println("any.isPresent() " + any.isPresent());
        System.out.println("any.isEmpty() " + any.isEmpty());
        // foreach
        stringList.stream().forEach(s -> {
            System.out.println("这个元素是:" + s);
        });
        // min / max
        Optional<String> min = stringList.stream().min(new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return String.CASE_INSENSITIVE_ORDER.compare(o1, o2);
            }
        });
        if (min.isEmpty())
            System.out.println("没有最小值");
        if (min.isPresent())
            System.out.println(min.get());
        // reduce
        Optional<String> reduce = stringList.stream().reduce(new BinaryOperator<String>() {
            @Override
            public String apply(String s, String s2) {
                return s + " + " + s2 ;
            }
        });
        reduce = stringList.stream().reduce((s, s2) -> s + " + " + s2);
        if (reduce.isPresent())
            System.out.println(reduce.get());
        else
            System.out.println("咋没有");


        // --------------流的拼接--------------
        // concat
        List<String> list1 = new ArrayList<>();
        List<String> list2 = new ArrayList<>();
        list1.add("123");
        list1.add("456");
        list2.add("789");
        list2.add("10");
        Stream<String> concat = Stream.concat(list1.stream(), list2.stream());
        System.out.println(concat.toList());
    }
}
